# 27. 对象、类方法、静态方法
# 属性
属性:将一个方法(函数)伪装成一个属性,在代码的级别上并没有本质的提升,但是可以让代码能够变得更合理
伪装后的属性也能拥有正常属性的删改查,但是需要我们做一些代码操作
# 属性初始 - 属性三部曲
有什么地方需要呢,一般来说在静态变量是不能赋值动态运算跟动态代码的,这时就可以用一个方法来接收,在用属性伪装来属性, 调用就跟正常的静态变量差不多
@property # 可以把方法伪装成属性
@方法名.setter # 修改,可以让方法类似于属性一样拥有修改功能,简单来说就是一旦执行修改操作,Python会默认定位执行setter下的方法
@方法名.deleter #删除,可以让方法类似于属性一样拥有删除功能,简单来说就是一旦执行删除操作,Python会默认定位执行deleter下的方法
# 来一个简单的伪装属性 - (@property)
计算人体的BMT值,算法:体重(kg)÷身高^2(m)
class Steward:
def __init__(self,name,weight,height):
print("小服务系统目前只支持计算BMT值")
self.name = name
self.__weight = weight
self.__height = height
@property
def BMT(self):
print("您的BMI值:%s ,请注意保重身体,小凡的服务到此结束。。。。。。" % (self.__weight/self.__height**2))
print("""
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
""")
weight = input("请输入您的体重(kg):")
height = input("请输入您的身高(M):")
s1 = Steward("江凡",int(weight),float(height))
s1.BMT
以上程序,整体设为小服务系统,肯定不止只有一个BMT运算服务,所以BMT运算服务需要用一个方法来实现,这样子 需要调用BMT这方法就需要调用方法一样,这样子不行,加上@property,就可以把方法伪装成为属性,这样子这个方 法要想被调用,就只能通过类似调用属性的代码去调用他
# 属性拥有修改功能 - (@方法名.setter)
class age:
def __init__(self,name,age):
self.name = name
self.__age = age
@property
def age(self):
print(self.__age)
@age.setter
def age(self,age):
self.__age = age
a1 = age("江凡",22)
a1.age
a1.age = "12"
a1.age
通过@age.setter,会发现,伪装的属性可以被修改,不过这样的修改还很基础,不够完善
class age:
def __init__(self,name,age):
self.name = name
self.__age = age
@property
def age(self):
print(self.__age)
@age.setter
def age(self,age):
if type(age) is int:
self.__age = age
else:
print("输入的数据,数据类型不是int类型")
a1 = age("江凡",22)
a1.age
a1.age = 12
a1.age
上面的代码,修改方法部分加了一点判断,判断想更新的数值是不是int类型的
# 属性拥有删除功能 - (@方法名.deleter)
class age:
def __init__(self,name,age):
self.name = name
self.__age = age
@property
def age(self):
print(self.__age)
@age.setter
def age(self,age):
if type(age) is int:
self.__age = age
else:
print("输入的数据,数据类型不是int类型")
@age.deleter
def age(self):
del self.__age
a1 = age("江凡",22)
del a1.age
a1.age
# 类方法
类方法:通过类名调用的方法,类方法中第一个参数名称跟普通方法的self一样,有个名称(cls),在调用类方法的时候,Python会自动将类空间地址传给cls
class a:
@classmethod
def so(cls):
print(cls)
a.so()
执行结果:
<class '__main__.a'>
# 类方法的应用场景 - 类方法三部曲
# 类中方法没有对象参与的类
在类中有些方法不需要对象参与的就可以使用类方法
class a:
name = "江凡"
age = "22"
@classmethod
def so(cls):
print("姓名:%s ,年龄:%s" %(cls.name,cls.age))
a.so()
以上实例,在不用实例化的情况下,可以使用类方法
# 对类中的静态变量进行修改用类方法
如果需要对类中的静态变量进行修改的话,也可以使用类方法
class a:
name = "江凡"
age = "22"
@classmethod
def so(cls):
cls.name = "江先生"
print(cls.name)
a.so()
print(a.name)
执行结果:
江先生
江先生
# 继承中,父类得到子类的类空间
在继承中,如果想要父类能调用子类的类空间一切对象的话,就可以使用类方法
class a:
@classmethod
def so(cls):
print("姓名:%s ,年龄:%s" %(cls.name,cls.age))
class b(a):
name = "江凡"
age = "22"
b.so()
执行结果:
姓名:江凡 ,年龄:22
在以上实例中,执行b.so(),子类中没有,去父类找,父类有,父类中的cls参数是子类的类空间地址
# 静态方法
静态方法跟直接外面写函数没有什么区别,但是最大的区别就是归类
可以提升代码的复用性,能增加代码的清晰度
class so:
@staticmethod
def a():
print("这是一个静态方法")
@staticmethod
def b():
print("这是一个静态方法")
@staticmethod
def c():
print("这是一个静态方法")
so.a()
so.b()
so.c()
执行结果:
这是一个静态方法
这是一个静态方法
这是一个静态方法
以上实例,静态方法可以用于归类存放,把功能或作用差不多的归类到一个类中
class str(object):
"""
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to 'strict'.
"""
def capitalize(self): # real signature unknown; restored from __doc__
"""
S.capitalize() -> str
Return a capitalized version of S, i.e. make the first character
have upper case and the rest lower case.
"""
return ""
def casefold(self): # real signature unknown; restored from __doc__
"""
S.casefold() -> str
。。。。。。
。。。。。。
。。。。。。
以上实例,上面代码是从str的详细文档中获取一小部分的,但是大概可以看出,str是一个主类,下面分部的都是str的 功能,从这样也可以看出来,有效的分类归类可以明显的提高代码的可读性